import os
import openai
import time
import json
import time
import re
from config import *

#这里需要使用在智增增上注册的账号中自己的API_SECRET_KEY
API_SECRET_KEY = openai_api
BASE_URL = "https://api.zhizengzeng.com/v1/"

#音色列表
voice_list = [
    {"老年人": {"老年奶奶":'ICL_zh_female_heainainai_tob', "婆婆":'zh_female_popo_mars_bigtts'}},
    {"40-50岁": {"邻居阿姨":'ICL_zh_female_linjuayi_tob'}},
    {"30-40岁": {"知识渊博的中年男性":'zh_male_yuanboxiaoshu_moon_bigtts', "湾区大叔":'zh_female_wanqudashu_moon_bigtts', "严肃的英国中年男性":'en_male_smith_mars_bigtts',
                 "成熟稳重的中年英国男性":'en_male_adam_mars_bigtts', "优雅绅士的中年英国男性":'en_male_dryw_mars_bigtts', "Sarah":'en_female_sarah_mars_bigtts',
                 "霸气的武则天":'zh_female_wuzetian_mars_bigtts', "威严的中年古代帝王":'zh_male_silang_mars_bigtts',"严肃的美国中年男性":'zh_male_wennuanahu_moon_bigtts'}},
    {"20-30岁": {"温暖阿虎":'zh_male_wennuanahu_moon_bigtts', "爽快思思":'zh_female_shuangkuaisisi_moon_bigtts', "京腔侃爷":'zh_male_jingqiangkanye_moon_bigtts',
                 "湾湾小何":'zh_female_wanwanxiaohe_moon_bigtts', "呆萌川妹":'zh_female_daimengchuanmei_moon_bigtts',"浩宇小哥":'zh_male_haoyuxiaoge_moon_bigtts',
                 "北京小爷":'zh_male_beijingxiaoye_moon_bigtts', "广西远舟":'zh_male_guangxiyuanzhou_moon_bigtts', "妹坨洁儿":'zh_female_meituojieer_moon_bigtts',
                 "豫州子轩":'zh_male_yuzhouzixuan_moon_bigtts', "Skye":'zh_female_shuangkuaisisi_moon_bigtts', "Harmony":'zh_male_jingqiangkanye_moon_bigtts',
                 "Brayan":'zh_male_shaonianzixin_moon_bigtts', "Morgan":'zh_male_jieshuonansheng_mars_bigtts',"Hope":'zh_female_jitangmeimei_mars_bigtts',
                 "Candy":'zh_female_tiexinnvsheng_mars_bigtts'}},
    {"10-20岁": {"少年梓辛":'zh_male_shaonianzixin_moon_bigtts', "邻家女孩":'zh_female_linjianvhai_moon_bigtts', "活泼女孩":'ICL_zh_female_huoponvhai_tob',
                 "萌丫头":'zh_female_mengyatou_mars_bigtts', "Cutey":'zh_female_mengyatou_mars_bigtts'}},
    {"10岁以下小孩": {"天才童声":'zh_male_tiancaitongsheng_mars_bigtts', "奶气萌娃":'zh_male_naiqimengwa_mars_bigtts', "病弱少女":'ICL_zh_female_bingruoshaonv_tob',
                    "樱桃丸子": 'zh_female_yingtaowanzi_mars_bigtts'}},
    {"旁白解说": {"东方浩然":'zh_male_dongfanghaoran_moon_bigtts', "悬疑解说":'zh_male_changtianyi_mars_bigtts', "少儿故事":'zh_female_shaoergushi_mars_bigtts',
                "磁性解说男声":'zh_male_jieshuonansheng_mars_bigtts', "解说小明":'zh_male_jieshuoxiaoming_moon_bigtts', "开朗姐姐":'zh_female_kailangjiejie_moon_bigtts',
                "甜美悦悦":'zh_female_tianmeiyueyue_moon_bigtts', "知性女声":'zh_female_zhixingnvsheng_mars_bigtts', "心灵鸡汤":'zh_female_xinlingjitang_moon_bigtts',
                "广告解说":'zh_male_chunhui_mars_bigtts', "儒雅青年":'zh_male_ruyaqingnian_mars_bigtts', "擎苍":'zh_male_qingcang_mars_bigtts',
                "霸气青叔":'zh_male_baqiqingshu_mars_bigtts', "鸡汤妹妹":'zh_female_jitangmeimei_mars_bigtts'}},
    {"智能系统": {"灿灿/Shiny":'zh_female_cancan_mars_bigtts', "甜美小源":'zh_female_tianmeixiaoyuan_moon_bigtts'}},
    {"英语听力播音员": {"Anna":'en_female_anna_mars_bigtts'}}
]

# input_file 对输入的文本进行处理，去掉多余的空行，处理后的文本存放在new_text文件夹中
def deal_files(read_path, write_path):
    """
    read_path:要读取的文本在的文件夹路径
    write_path:存放处理后文件的文件夹路径
    对原文文本进行一个处理，去掉文本中的空行
    """
    for filename in os.listdir(read_path):
        if filename.endswith('.txt'):
            old_path = os.path.join(read_path, filename)
            new_path = os.path.join(write_path, filename)

            #读取原文
            with open(old_path, 'r', encoding='utf-8', errors='ignore') as old_file:
                lines = old_file.readlines()

            #将处理后内容写入新的txt文件中
            with open(new_path, 'w', encoding='utf-8') as new_file:
                for line in lines:
                    if line.strip():
                        new_file.write(line)

# 识别输入文本中的角色
def chat_completions1(text_content):

    openai.api_key = API_SECRET_KEY
    openai.api_base = BASE_URL

    prompt = f"""
             请根据输入的文本内容，按照从前往后的顺序逐行进行分析，不要遗漏文本中的内容，将输入文本划分为旁白或人物对话，并严格按照给出的JSON格式输出。
             扫描一整行的文本，标记出现的“”或【】。
             如果当前文本中出现了“”或【】，表示文本属于人物对话。对于判断为人物对话的文本，可以通过上下文搜索判断对话的说话人是谁，即为"speaker"的值，"content"的值就是位于中“”或【】内部的文本。并根据文本内容分析判断说话人的情感"emotion"的值和性别"sex"的值。
             如果整行文本中不存在“”或【】，则表示该文本属于旁白。对于判断为旁白的文本，"info"中"speaker"的值为"旁白","content"的值即为这段文本的内容。并根据文本内容判断这段内容的情感色彩。
             划分的示例如下：
             例句：但有一年的秋季，大约是得到祥林嫂好运的消息之后的又过了两个新年，她竟又站在四叔家的堂前了。
             划分：当前句子没有对话，即不存在“”或【】，那么"speaker"的值为"旁白"，"content"的值为整个句子的内容，情感色彩即"emotion"的值为"有一点惊讶"。
             例句：“祥林嫂，你放着罢!我来拿。”四婶又慌忙的说。
             划分：当前句子出现对话，即存在“”或【】，那么通过上下文寻找说话角色"speaker"为：四婶，"sex"的值为"female"，"emotion"的值为"着急，慌忙"，"content"的值为位于“”或【】内部的文本。
             结果使用的JSON格式主要包括两个部分"type"和"info"，其中"type"的值都为"人声"，"info"中是详细信息。
             如果"info"的"speaker"值为"旁白"，则"info"包含"speaker","emotion"，"voice_type"(值为空)和"content";否则，"info"包含"speaker","sex","emotion","voice_type"(值为空)和"content"。
             具体要求如下：
             -序号（按先后顺序排列）
              -"type":"人声"
              -"info"（划分的详细信息）:
               -"speaker":说话的人
               -"sex":性别（female或male）
               -"emotion":情感色彩
               -"voice_type":null,值为空
               -"content":字符串类型，表示文本内容
             或者
             -序号（按先后顺序排列）
              -"type":"人声"
              -"info"（划分的详细信息）:
               -"speaker":旁白
               -"emotion":情感色彩
               -"voice_type":null,值为空
               -"content":字符串类型，表示文本内容
             文本内容如下：{text_content}
             最终结果严格按照JSON格式输出，示例如下：
             {{
                "1": {{
                  "type": "人声",
                  "info": {{
                    "speaker": "旁白",
                    "emotion": "有一点点惊讶",
                    "voice_type":null
                    "content": "但有一年的秋季，大约是得到祥林嫂好运的消息之后的又过了两个新年，她竟又站在四叔家的堂前了。"
                  }}
                }},
             }}
             """
    # 接受gpt-4o的输出回答
    resp = openai.ChatCompletion.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "你是一个精通于分析文本内容的专家。根据下面用户提供的文本执行相应的任务"},
            {"role": "user", "content": prompt},
        ]
    )
    # print(resp)
    # print(resp.choices[0].message.content)
    return resp.choices[0].message.content

# 将输入内容转化为json
def get_json(resp_data):
    # 使用正则表达式去除大模型输出结果前面和后面多余的内容
    cleaned_content = re.sub(r'^```json\s*', '', resp_data).strip()
    cleaned_output = re.sub(r'```\s*$', '', cleaned_content)
    # 去掉转移字符
    cleaned_json_str = cleaned_output.replace('\\', '')
    # print(cleaned_json_str)
    return cleaned_json_str

# 对第一次文本输出内容进行处理,添加背景音
def chat_completions2(text_content):
    #定义存放角色和对应音色的字典
    voice_dict = {}

    openai.api_key = API_SECRET_KEY
    openai.api_base = BASE_URL

    prompt = f"""
             请按照从前往后的顺序对JSON文本进行处理，并将结果严格按照JSON的格式进行输出。
             要执行的任务是，寻找"speaker"值为"旁白"的json对象，判断后面是否需要添加环境声。
             首先，第一步，对每一个json对象，判断"speaker"的值是否为"旁白",如果不是，则不对当前json对象进行修改，且将当前json对象按顺序放入输出结果中，继续分析下一个，如果是，进行第二步。
             第二步判断，判断"content"中是否存在可以制造声音的动词词组，如果不存在，则不对当前json对象进行修改，且将当前json对象按顺序放入输出结果中，继续分析下一个，如果存在，执行第三步。
             第三步，标记制造声音的动词词组，判断这个动词词组是否表示说话这一类动作，如果是，则不对当前json对象进行修改，且将当前json对象按顺序放入输出结果中，继续分析下一个，如果不是，执行第四步。
             第四步，按照顺序在当前的json对象后面添加一个新的json对象，其中"type"值为"环境声"，"info"值为英文描述的被标记的动词产生的声音。
             判断示例如下：
             数据：
             {{
                "9": {{
                  "type": "人声",
                  "info": {{
                    "speaker": "旁白",
                    "emotion": "同情，悲伤",
                    "voice_type":null
                    "content": "她接着但是呜咽，说不出成句的话来。"
                  }}
                }},
             }}
             判断：第一步，"speaker"值为"旁白"，执行第二步。第二步，"content"中存在可以制造声音的动词词组“呜咽”，执行第三步。
                  第三步，“呜咽”不属于表示说话的动词，执行第四步。
                  第四步，按照顺序在当前的json对象后面添加一个新的json对象，其中"type"值为"环境声"，"info"值为英文描述的被标记的动词产生的声音，即为"a middle-aged woman was sobbing"。
             输入的数据内容如下：{text_content}
             最终结果严格按照JSON格式输出，示例如下：
             {{
                "9": {{
                  "type": "人声",
                  "info": {{
                    "speaker": "旁白",
                    "emotion": "同情，悲伤",
                    "voice_type":null
                    "content": "她接着但是呜咽，说不出成句的话来。"
                  }}
                }},
                "10": {{
                  "type": "环境声",
                  "info": "a middle-aged woman was sobbing"
                }},
             }}
             """

    resp = openai.ChatCompletion.create(
        model="gpt-4o",
        messages=[
            {"role": "user", "content": prompt},
        ]
    )
    # print(resp.choices[0].message.content)
    return resp.choices[0].message.content

# 选取合适的音色
def chat_completions3(text_content, voice_list):
    #定义存放角色和对应音色的字典
    voice_dict = {}

    openai.api_key = API_SECRET_KEY
    openai.api_base = BASE_URL

    prompt = f"""
             请按照从前往后的顺序对JSON文本进行处理，并将结果严格按照JSON的格式进行输出。
             要执行的任务是，从音色列表中选择合适的音色。
             首先，第一步，对每一个json对象，查看"type"的值。如果"type"的值为"环境声"，则不对当前json对象进行修改，且将当前json对象按顺序放入输出结果中，继续分析下一个。如果"type"的值为"人声",进行第二步判断。
             第二步判断，首先判断"speaker"的值是否出现在音色字典中，如果出现，"voice_type"的值就是"speaker"的值在音色字典中对应的value值，如果没有出现，进行第三步判断。
             第三步判断，如果"speaker"的值为"旁白"，执行“后面步骤”，否则进行第四步。
             “后面步骤”:从音色列表的"旁白解说"部分的值中选择一个最适合的音色，作为"voice_type"的值，并将"speaker"的值和"voice_type"的值组成的key,value对放入到音色字典中。
             第四步，根据"speaker"判断角色的年龄范围和身份，确定从音色列表哪一个区域内选择，之后根据"sex"判断选男性音色还是女性音色，选择一个最合适的音色作为"voice_type"的值，并将"speaker"的值和"voice_type"的值组成的key,value对放入到音色字典中。
             判断示例如下：
             数据：
             {{
                "1": {{
                  "type": "人声",
                  "info": {{
                    "speaker": "旁白",
                    "emotion": "有一点点惊讶",
                    "voice_type":null
                    "content": "但有一年的秋季，大约是得到祥林嫂好运的消息之后的又过了两个新年，她竟又站在四叔家的堂前了。"
                  }}
                }},
             }}
             判断：第一步，"type"值为"人声"，执行第二步。第二步，查看音色字典，发现"speaker"值没有在字典中出现，执行第三步。
                  第三步，"speaker"值为"旁白"，则从音色列表的"旁白解说"部分的值中选择一个最适合的音色，即"voice_type"的值修改为"zh_male_jieshuonansheng_mars_bigtts"
             输入的数据内容如下：{text_content}
             音色列表如下：{voice_list}
             音色字典如下：{voice_dict}
             最终结果严格按照JSON格式输出，示例如下：
             {{
                "1": {{
                  "type": "人声",
                  "info": {{
                    "speaker": "旁白",
                    "emotion": "有一点点惊讶",
                    "voice_type":"zh_male_jieshuonansheng_mars_bigtts"
                    "content": "但有一年的秋季，大约是得到祥林嫂好运的消息之后的又过了两个新年，她竟又站在四叔家的堂前了。"
                  }}
                }},
             }}
             """

    resp = openai.ChatCompletion.create(
        model="gpt-4o",
        messages=[
            {"role": "user", "content": prompt},
        ]
    )
    # print(resp.choices[0].message.content)
    return resp.choices[0].message.content


# output_file 将gpt-4o的输出结果使用json文件存储，存放的文件夹为output
def output_file(json_data, write_path):
    """
    将模型的回答写到json文件中
    """
    cleaned_json_str = get_json(json_data)
    with open(write_path, 'w', encoding='utf-8') as file:
        file.write(cleaned_json_str)

# 完整的处理流程
def transform_to_json(file_path):
    """
        file_path:要提供给gpt-4o模型的文本在的文件夹路径
        write_path:存放处理后json文件的文件夹路径
        通过gpt-4o模型，对文件夹中的全部内容进行处理，按照指定的json格式输出json文件
        """
    for filename in os.listdir(file_path):
        if filename.endswith('.txt'):
            read_path = os.path.join(file_path, filename)
            write_path = os.path.join(file_path, filename.replace('.json', '.txt'))

            # 读取文本内容
            with open(read_path, 'r', encoding='utf-8') as input_file:
                content = input_file.read()
            #获取gpt-4o的输出结果
            # data = chat_completions(content, voice_list)
            # # 将处理后内容写入json文件中
            # output_file(data, write_path)

if __name__ == '__main__':

    # deal_files('./origin_text', './new_text')
    # with open("./new_text/祝福_节选.txt",'r',encoding='utf-8') as file:
    #     file_content = file.read()
    # json_data = chat_completions(file_content, voice_list)
    # output_file(json_data, './output/test3.json')
    with open("./new_text/祝福_节选.txt",'r',encoding='utf-8') as file:
        file_content = file.read()
    res_data1 = chat_completions1(file_content)
    data1 = get_json(res_data1)
    res_data2 = chat_completions2(data1)
    data2 = get_json(res_data2)
    json_data = chat_completions3(data2, voice_list)
    # json_data = chat_completions(file_content, voice_list)
    output_file(json_data, './output/祝福_节选2.json')